/*
  DigitalReadSerial
 Reads a digital input on pin 2, prints the result to the serial monitor 
 
 This example code is in the public domain.
 */

#define SENSOR_TYPE_BUTTON 1;

#define ACTUATOR_TYPE_RELAY 1;

#define WHEN_OPEN 1;
#define WHEN_CLOSE 2;
//de la direccion 1 a la x
class Sensor {
public:
  int id;
  int type;
  int the_port;
  int state;
  long lastRead;
  long lastReadDown;
};


class Actuator {
public:
  int id;
  int port;
  int state;
  int type;
};

class SensorAction {
public:
  int id_sensor;
  int actuate_when; 
  int id_actuator;

};

int NUM_SENSORS=0;
int NUM_ACTUATORS = 0;
int NUM_ACTIONS = 0;
Sensor sensors[50];
Actuator actuator[50];
SensorAction actions[100];


bool house_state = true;
int sensorValue =0;
//boolean sensorState[20];
//boolean releState[20] ;
//long lastRead[20];
//long lastReadDown[20];
void setup() {

//SENSORES----------------
    //Dormitorio
    addSensor(1,14,1);
    
    addSensor(2,15,1);
    //Despacho
    addSensor(3,16,1); 
    //Cocina ( de los 4 el 1o)
    addSensor(4,17,1);
    //Pasillo  ( de los 4 el 3o)
    addSensor(5,2,1);
    addSensor(6,5,1);
    addSensor(7,4,1);
    addSensor(8,5,1);
    //Lavavo
    addSensor(9,13,1);
    //Invitados mesita de dormir..
    addSensor(10,12,1);
    //Pasillo  ( de los 4 el 4o)
    addSensor(11,7,1);
    
    
    //el  puerto 6 no funciona!!!
    
//ACTUADORES----------------   
    
   //Dormitorio
   addActuator(1,42,0);
   //Dspacho encima mesa
   addActuator(2,43,0);
   //parece que es el distribuidor
   addActuator(3,44,0);
   //Pasillo
   addActuator(4,45,0);
   //Cocina
   addActuator(5,38,0);
   //???
   addActuator(6,39,0);
   //Comedor-Sofa
   addActuator(7,40,0);
   
   //Despacho estanteria
   addActuator(8,41,0);
   //??-- no conectado
   addActuator(9,34,0);
   //????
   addActuator(10,35,0);
   //????
   addActuator(11,36,0);
   //
   addActuator(12,37,0);
   addActuator(13,32,0);
   //Comedor tele
   addActuator(14,33,0);
   //Lavavo
   addActuator(15,22,0);
   


   addAction(2,13);
   addAction(2,4);
   addAction(2,7);
   addAction(4,3);
   //Despacho..
   addAction(3,2);
   addAction(3,8);
   //Pasillo..
   addAction(5,5);
   //Cocina
   addAction(11,4);
   addAction(11,15);
   //Comedor
   addAction(4,7);
   addAction(4,14);
   //Dormitorio
   addAction(1,1);
   //Lavavo
   addAction(9,15);
//HASTA AKI BUENOS...


  //BY DEFAULT
  for (int i =0 ; i < NUM_SENSORS ; i++){
    sensors[i].state =0;
    sensors[i].lastRead =  millis();
    sensors[i].lastReadDown =0;
    pinMode(sensors[i].the_port,INPUT);
  }

  for (int i = 0;i < NUM_ACTUATORS;i++){
    pinMode(actuator[i].port,OUTPUT);
  }
  Serial.begin(9600);
}

void loop() {

  for ( int a = 0 ; a < NUM_SENSORS; a++){
    int sensor_state;
    sensor_state = digitalRead(sensors[a].the_port);

    if (sensors[a].type == 1 ){ 
      if (sensor_state == HIGH &&  ( millis() - sensors[a].lastRead ) >300){
        Serial.print("Sensor leido ");
         Serial.println(sensors[a].id);
        //Sensor esta activo y hace mas de 300 milis que no se lee...
        if ((millis() - sensors[a].lastReadDown) > 50 ){
          
          //EL SENSOR SE MANTIENE APRETADO MAS DE 50 milis
          sensors[a].lastRead = millis();
          //SE HA APRETADO EL SENSOR!!!

          if (sensors[a].id == 7  ){
             house_state = ! house_state;
            for (int i = 0; i < NUM_ACTUATORS; i++){
              if ( house_state == false){
                digitalWrite( actuator[i].port, LOW);
              }
              else{

              digitalWrite( actuator[i].port, actuator[i].state);
              }
            }
          }
           else{
             sensor_button_click(sensors[a].id);
           }
          //HAY QUE VER LAS ACCIONES QUE LE TOCAN HACER
        }
        else{         
         
        }
      }
      else{
         sensors[a].lastReadDown = millis();
      }
    }
  }
  readSerial();
 

}

void readSerial(){
  
   //LEEMOS DEL SERIAL
  int incoming;
  if (Serial.available() > 0) {
    
    // read the incoming byte:
    incoming = Serial.read();
    
    if (incoming == 101){
      int x = readInt();

       
      for (int i = 0 ; i < NUM_ACTUATORS ; i++){
        
        if (  actuator[i].id == x ){
          actuator[i].state = 1; 
          digitalWrite( actuator[i].port, actuator[i].state);
          Serial.print("Activating actuator: ");
          Serial.println(actuator[i].id, DEC);
        }
      }
    }
    else if (incoming == 100){
      int x = readInt();


      for (int i = 0 ; i < NUM_ACTUATORS ; i++){
        if (  actuator[i].id == x ){
          actuator[i].state = 0; 
          digitalWrite( actuator[i].port, actuator[i].state);
          Serial.print("DEActivating actuator: ");
          Serial.println(actuator[i].id, DEC);
        }
      }
    }
    else{
      Serial.print("Reciving incorrect data ");

    }

  }
  
  
  
}

void addSensor(int id, int port, int type){
  sensors[NUM_SENSORS].id = id;
    sensors[NUM_SENSORS].the_port = port;
    sensors[NUM_SENSORS].type = type;
    NUM_SENSORS ++;
}
void addActuator(int id, int port,int type){
   actuator[NUM_ACTUATORS].id = id;
   actuator[NUM_ACTUATORS].port = port;
  actuator[NUM_ACTUATORS].state = 0;
  actuator[NUM_ACTUATORS].type = type;
  NUM_ACTUATORS ++;
  
}
void addAction(int id_sensor,int id_actuator ){
  actions[NUM_ACTIONS].id_sensor = id_sensor; 
  actions[NUM_ACTIONS].id_actuator =id_actuator;
  NUM_ACTIONS++;
}


int readInt (){
  int x;
  while  (Serial.available() <= 0) {

  }
  x =( Serial.read()-48) *10;       

  while  (Serial.available() <= 0) {

  }
  x += Serial.read()-48;



  return x;

}
void  sensor_button_click(int id_sensor){
  Serial.print("Sensor ");
  Serial.println(id_sensor);

  //Leemos el listado de acciones para el evento x

  for (int x=0 ; x< NUM_ACTIONS; x++){
    if (actions[x].id_sensor == id_sensor){

      //Buscamos cual es su actuador....
      
      for ( int y = 0; y < NUM_ACTUATORS; y++){
        if (actuator[y].id == actions[x].id_actuator){
          if (actuator[y].state == 0  ){
              actuator[y].state =1;
          }
          else {
            actuator[y].state = 0;
          }
          Serial.print("Actuator ");
          Serial.println(actuator[y].port);
          digitalWrite( actuator[y].port, actuator[y].state);
        }
      }
    }
  }
}




